// /////////////////////////////////////////////////////////////////////////////
//
// Name:            SerializedAttributesImpl.h
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Declarations of various subclasses of the
//                  SerializedAttribute class.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __SERIALIZEDATTRIBUTEIMPL_H__
#define __SERIALIZEDATTRIBUTEIMPL_H__

// Include files
#include "SerializedAttribute.h"


// SerializedAabbox3d class
//! SerializedAttribute subclass for serialized aabbox3d objects.
class SerializedAabbox3d : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor (aabbox3df)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedAabbox3d(const std::string &name, const aabbox3df &value);
    //! Constructor (aabbox3di)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedAabbox3d(const std::string &name, const aabbox3di &value);
    //! Deconstructor
    ~SerializedAabbox3d();

    // Public methods
    aabbox3df    getAabbox3df();
    aabbox3di    getAabbox3di();
    std::string  getString();

	void setAabbox3df(const aabbox3df &value);
    void setAabbox3di(const aabbox3di &value);
    void setString(const std::string &value);

private:

    // Private methods
    template<typename R, typename T>
    aabbox3d<R> convert(const aabbox3d<T> &t)
    {
       aabbox3d<R> r;

       r.MinEdge.X = (R)t.MinEdge.X;
       r.MinEdge.Y = (R)t.MinEdge.Y;
       r.MinEdge.Z = (R)t.MinEdge.Z;

       r.MaxEdge.X = (R)t.MaxEdge.X;
       r.MaxEdge.Y = (R)t.MaxEdge.Y;
       r.MaxEdge.Z = (R)t.MaxEdge.Z;

       return r;
    }

    // Private members
    aabbox3d<f64> mValue;
};


// SerializedBool class
//! SerializedAttribute subclass for boolean values.
class SerializedBool : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedBool(const std::string &name, bool value);
    //! Deconstructor
    ~SerializedBool();

    // Public methods
    bool         getBool();
    f32          getFloat();
    s32          getInt();
    std::string  getString();

	void setBool(bool value);
	void setFloat(f32 value);
	void setInt(s32 value);
	void setString(const std::string &value);

private:

    // Private members
    bool mValue;
};


// SerializedColor
//! SerializedAttribute subclass for serialized color objects.
class SerializedColor : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedColor(const std::string &name, const SColorf &value);
    //! Deconstructor
    ~SerializedColor();

    // Public methods
    SColor       getColor();
    SColorf      getColorf();
    f32          getFloat();
    s32          getInt();
    std::string  getString();

    void setColor(const SColor &value);
    void setColorf(const SColorf &value);
	void setFloat(f32 value);
	void setInt(s32 value);
	void setString(const std::string &value);

private:

    // Private members
    SColorf mValue;
};


// SerializedDimension2d class
//! SerializedAttribute subclass for serialized dimension2d objects.
class SerializedDimension2d : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor (dimension2df)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedDimension2d(const std::string &name, const dimension2df &value);
    //! Constructor (dimension2di)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedDimension2d(const std::string &name, const dimension2di &value);
    //! Deconstructor
    ~SerializedDimension2d();

    // Public methods
    std::string  getString();
    dimension2df getDimension2df();
    dimension2di getDimension2di();

	void setDimension2df(const dimension2df &value);
    void setDimension2di(const dimension2di &value);
    void setString(const std::string &value);

private:

    // Private methods
    template<typename R, typename T>
    dimension2d<R> convert(const dimension2d<T> &t)
    {
       return dimension2d<R>((R)t.Width, (R)t.Height);
    }

    // Private members
    dimension2d<f64> mValue;
};


// SerializedLine2d class
//! SerializedAttribute subclass for serialized line2d objects.
class SerializedLine2d : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor (line2df)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedLine2d(const std::string &name, const line2df &value);
    //! Constructor (line2di)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedLine2d(const std::string &name, const line2di &value);
    //! Deconstructor
    ~SerializedLine2d();

    // Public methods
    std::string  getString();
    line2df      getLine2df();
    line2di      getLine2di();

	void setLine2df(const line2df &value);
    void setLine2di(const line2di &value);
    void setString(const std::string &value);

private:

    // Private methods
    template<typename R, typename T>
    line2d<R> convert(const line2d<T> &t)
    {
       line2d<R> r;

       r.start.X = (R)t.start.X;
       r.start.Y = (R)t.start.Y;

       r.end.X = (R)t.end.X;
       r.end.Y = (R)t.end.Y;

       return r;
    }

    // Private members
    line2d<f64> mValue;
};


// SerializedLine3d class
//! SerializedAttribute subclass for serialized line3d objects.
class SerializedLine3d : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor (line3df)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedLine3d(const std::string &name, const line3df &value);
    //! Constructor (line3di)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedLine3d(const std::string &name, const line3di &value);
    //! Deconstructor
    ~SerializedLine3d();

    // Public methods
    std::string  getString();
    line3df      getLine3df();
    line3di      getLine3di();

	void setLine3df(const line3df &value);
    void setLine3di(const line3di &value);
    void setString(const std::string &value);

private:

    // Private methods
    template<typename R, typename T>
    line3d<R> convert(const line3d<T> &t)
    {
       line3d<R> r;

       r.start.X = (R)t.start.X;
       r.start.Y = (R)t.start.Y;
       r.start.Z = (R)t.start.Z;

       r.end.X = (R)t.end.X;
       r.end.Y = (R)t.end.Y;
       r.end.Z = (R)t.end.Z;

       return r;
    }

    // Private members
    line3d<f64> mValue;
};


// SerializedNumber class
//! SerializedAttribute subclass for number values.
class SerializedNumber : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor (s32)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedNumber(const std::string &name, s32 value);
    //! Constructor (f32)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedNumber(const std::string &name, f32 value);
    //! Deconstructor
    ~SerializedNumber();

    // Public methods
    bool         getBool();
    f32          getFloat();
    s32          getInt();
    std::string  getString();

	void setBool(bool value);
	void setFloat(f32 value);
	void setInt(s32 value);
	void setString(const std::string &value);

private:

    // Private members
    f64 mValue;
};


// SerializedObject class
//! SerializedAttribute subclass for Serializable objects.
//! @note The Serializable class doesn't derive from the ReferencedCounted. So it's up to the
//!       programmer to make sure that the referenced object is available when it's needed.
//!       Normally this shouldn't be a problem as SerializedAttribute subclasses are supposed
//!       to be used (and deleted) shortly after initialisation.
class SerializedObject : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor
    //! @param name          Name of the attribute
    //! @param object        Pointer to Serializable object.
    SerializedObject(const std::string &name, Serializable *object);
    //! Deconstructor
    ~SerializedObject();

    // Public methods
    Serializable* getObject();

    void setObject(Serializable *object);

private:

    // Private members
    Serializable *mObject;
};


// SerializedPlane3d class
//! SerializedAttribute subclass for serialized plane3d objects.
class SerializedPlane3d : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor (plane3df)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedPlane3d(const std::string &name, const plane3df &value);
    //! Constructor (plane3di)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedPlane3d(const std::string &name, const plane3di &value);
    //! Deconstructor
    ~SerializedPlane3d();

    // Public methods
    std::string  getString();
    plane3df     getPlane3df();
    plane3di     getPlane3di();

	void setPlane3df(const plane3df &value);
    void setPlane3di(const plane3di &value);
    void setString(const std::string &value);


private:

    // Private methods
    template<typename R, typename T>
    plane3d<R> convert(const plane3d<T> &t)
    {
       plane3d<R> r;

       r.Normal.X = (R)t.Normal.X;
       r.Normal.Y = (R)t.Normal.Y;
       r.Normal.Z = (R)t.Normal.Z;

       r.D = (R)t.D;

       return r;
    }

    // Private members
    plane3d<f64> mValue;
};


// SerializedQuaternion class
//! SerializedAttribute subclass for serialized quaternion objects.
class SerializedQuaternion : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedQuaternion(const std::string &name, const quaternion &value);
    //! Deconstructor
    ~SerializedQuaternion();

    // Public methods
    std::string  getString();
    quaternion   getQuaternion();

	void setQuaternion(const quaternion &value);
	void setString(const std::string &value);


private:

    // Private members
    quaternion mValue;
};


// SerializedRect class
//! SerializedAttribute subclass for serialized rect objects.
class SerializedRect : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedRect(const std::string &name, const rect<s32> &value);
    //! Deconstructor
    ~SerializedRect();

    // Public methods
    std::string  getString();
    rect<s32>    getRect();

	void setRect(const rect<s32> &value);
	void setString(const std::string &value);

private:

    // Private members
    rect<s32> mValue;
};


// SerializedString class
//! SerializedAttribute subclass for serialized strings.
class SerializedString : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor (std::string)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedString(const std::string &name, const std::string &value);
    //! Constructor (stringw)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedString(const std::string &name, const stringw &value);
    //! Deconstructor
    ~SerializedString();

    // Public methods
    std::string  getString();
    stringw      getStringW();

	void setString(const std::string &value);
	void setStringW(const stringw &value);

private:

    // Private members
    stringw mValue;
};


// SerializedVector2d class
//! SerializedAttribute subclass for serialized vector2d objects.
class SerializedVector2d : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor (vector2df)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedVector2d(const std::string &name, const vector2df &value);
    //! Constructor (vector2di)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedVector2d(const std::string &name, const vector2di &value);
    //! Constructor (vector2d<f64>)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedVector2d(const std::string &name, const vector2d<f64> &value);
    //! Deconstructor
    ~SerializedVector2d();

    // Public methods
    std::string  getString();
    vector2df    getVector2df();
    vector2di    getVector2di();

    void setString(const std::string &value);
	void setVector2df(const vector2df &value);
    void setVector2di(const vector2di &value);

private:

    // Private methods
    template<typename R, typename T>
    vector2d<R> convert(const vector2d<T> &t)
    {
       return vector2d<R>((R)t.X, (R)t.Y);
    }

    // Private members
    vector2d<f64> mValue;
};


// SerializedVector3d class
//! SerializedAttribute subclass for serialized vector3d objects.
class SerializedVector3d : public SerializedAttribute
{
public:

    // Initialisation and deinitialisation
    //! Constructor (vector3df)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedVector3d(const std::string &name, const vector3df &value);
    //! Constructor (vector3di)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedVector3d(const std::string &name, const vector3di &value);
    //! Constructor (vector3d<f64>)
    //! @param name          Name of the attribute
    //! @param value         Initial value of this attribute.
    SerializedVector3d(const std::string &name, const vector3d<f64> &value);
    //! Deconstructor
    ~SerializedVector3d();

    // Public methods
    std::string  getString();
    vector3df    getVector3df();
    vector3di    getVector3di();

    void setString(const std::string &value);
	void setVector3df(const vector3df &value);
    void setVector3di(const vector3di &value);

private:

    // Private methods
    template<typename R, typename T>
    vector3d<R> convert(const vector3d<T> &t)
    {
       return vector3d<R>((R)t.X, (R)t.Y, (R)t.Z);
    }

    // Private members
    vector3d<f64> mValue;
};

#endif
